package main

import (
	_ "GraduationProject/public/tools"
	_ "GraduationProject/worker/client"
	"GraduationProject/worker/conf"
	"GraduationProject/worker/fengchedm"
	"encoding/json"
	"log"
	"os/signal"
	"syscall"
	"time"

	"GraduationProject/public/db"
	"GraduationProject/public/models"
	"GraduationProject/public/params"
	"GraduationProject/public/status"
	"GraduationProject/public/tools"
	"GraduationProject/worker/client"
	"GraduationProject/worker/neteasy_music"
	"GraduationProject/worker/worker_tools"
	"flag"
	"fmt"
	"os"
	"strconv"
)

var (
	newWorkerID = flag.Bool("newWorkerID", false, "get worker ID.")
)

func init() {
	flag.Parse()

	workerIDStr := tools.Conf.Get("worker_id")
	if *newWorkerID {
		fmt.Println("get worker ID")
		//workerIDStr := tools.Conf.Get("worker_id")
		if workerIDStr == "" || workerIDStr == "0" {
			machineID, err := strconv.Atoi(tools.Conf.Get("machine_id"))
			if err != nil {
				panic("machine_id atoi error" + err.Error())
			}
			response := client.NewWorkerID(client.EngineClient, models.Worker{
				MachineID: uint(machineID),
			})
			fmt.Printf("response: %#v\n", response)
			if response.Status == status.WorkerIDRevised {
				tools.Conf.Set("worker_id", response.Message)
				fmt.Printf("%#v\n", tools.Conf)
				if err := tools.Conf.Save(); err != nil {
					panic("save worker_id error: " + err.Error())
				}
			}
		}
		os.Exit(0)
	}
	if workerIDStr == "" || workerIDStr == "0" {
		panic("worker_id not found")
	}
	db.ConnectDB()
	db.RedisConnect()
	db.ElasticSearchConnect()
	db.DB.Model(&models.Worker{}).
		Where("id = ?", tools.Conf.Get("worker_id")).
		Update("status", models.WorkerPause)
}

var (
	// 通过修改此处，可编译不同版本
	//function = neteasy_music.Run
	functions = []func(seed models.Record) (result params.Result, err error){
		neteasy_music.Run,
		fengchedm.Run,
	}
)

func main() {
	for i := 0; i < 4; i++ {
		go run()
	}
	sign := make(chan os.Signal)
	signal.Notify(sign, syscall.SIGINT, syscall.SIGTERM)
	for {
		// 接收信号量
		sig := <-sign
		log.Printf("signal receive: %v\n", sig)
		switch sig {
		case syscall.SIGINT, syscall.SIGTERM:
			// 关闭服务
			db.DB.Model(&models.Worker{}).
				Where("id = ?", tools.Conf.Get("worker_id")).
				Update("status", models.WorkerStop)
			db.Redis.HSet(models.WorkerStatusKey, tools.Conf.Get("worker_id"), models.WorkerPause)
			log.Println("shutdown")
			// 停止该程序
			signal.Stop(sign)
			return
		}
	}
}

func run() {
	for {
		if worker_tools.IsStopped(tools.Conf.Get("worker_id")) {
			//log.Printf("worker %s stopped\n", tools.Conf.Get("worker_id"))
			time.Sleep(time.Second * 3)
			continue
		}
		seed := <-client.SeedChannel
		fmt.Printf("seed: %#v\n", seed)
		// todo: redis 去重 url+params
		if !worker_tools.DuplicateRemoval(seed) {
			for _, fn := range functions {
				result, err := fn(seed)
				bytes, _ := json.Marshal(result)
				fmt.Printf("result: %s,\terror: %v\n", bytes, err)
				if err == conf.ErrDefault {
					continue
				}
				for i := range result.Seeds {
					result.Seeds[i].SeedID = seed.SeedID
				}

				resp := client.PushResult(client.EngineClient, result)
				fmt.Printf("response: %#v\n", resp)
				break
			}

		}
	}
}
